package com.vert.model;

import com.alibaba.fastjson.JSONObject;
import com.vert.annotations.Param;
import com.vert.handler.HttpHandler;
import com.vert.utils.ObjectMaps;
import com.vert.utils.ObjectTypeUtils;
import com.vert.utils.StringUtils;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.FileUpload;
import io.vertx.ext.web.RequestBody;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.multipart.MultipartForm;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @Classname HttpBody
 * @Description TODO
 * @Date 2022/5/24 17:15
 * @Created by XiongXiong
 * @Author: X.I.O
 */
public class HttpBody {


  private  HttpHandler httpHandler;

  public Handler<RoutingContext>body(Method method, Object obj, Class<?>[] clazzs){
    return routingContext -> {
      Object objStr=null;
      try {

      // String path= this.getClass().getResource("/").getPath();

        List<FileUpload> uploads = routingContext.fileUploads();
        List<Object> objList=new ArrayList<Object>();
        MultiMap multiMap=routingContext.queryParams();


        MultipartForm multipartForm = MultipartForm.create();
        MultiMap attributes = routingContext.request()
          .formAttributes();

        attributes.forEach(attribute -> {
            multipartForm.attribute(attribute.getKey(), attribute.getValue());
        });


       if(clazzs.length>0){
             for (int i = 0; i < clazzs.length; i++) {
               Class<?> cls=clazzs[i];
               Annotation[][] annotations= method.getParameterAnnotations();
               Annotation[] an=annotations[i];
               if(cls.getName().equals(HttpServerResponse.class.getName())){
                    objList.add(routingContext.response());
               }else if(cls.getName().equals(HttpServerRequest.class.getName())) {
                   HttpServerRequest request = routingContext.request();
                   objList.add(request);
               }else if (an.length>0) {
                    //处理注解
                    dealAnnationParamHandler(objList,an,cls,routingContext,multiMap);
               }else if(cls.getName().equals(UploadBody.class.getName())){

                 objList.add(null);
               }else {
                 objList.add(null);
               }
             }
             if(httpHandler==null){
                Object httpHandlerObj= ObjectMaps.getObjectByClass(HttpHandler.class);
                if(httpHandlerObj != null){
                    httpHandler=(HttpHandler)httpHandlerObj;
                }
             }
             if(httpHandler!=null){
                httpHandler.bedoreHandler(objList.toArray());
             }

              objStr=method.invoke(obj,objList.toArray());

             if(httpHandler!=null){
                 Object value=httpHandler.afterHandler(objList.toArray(),objStr);
                 if(value != null){
                    objStr=value;
                 }
             }
       }else {
          objStr=method.invoke(obj);
       }
      }catch (Exception e) {
        e.printStackTrace();
      }
      routingContext.response().putHeader("content-type", "application/json; charset=utf-8")
        .end(JSONObject.toJSONString(objStr));
    };
  }

  //处理注解
  private void dealAnnationParamHandler(List<Object> objList, Annotation[] an,Class<?> cls,RoutingContext routingContext,MultiMap multiMap){
        Param param = paramFieldHandler(an);
        com.vert.annotations.RequestBody requestBody=requestBodyHandler(an);
          if (multiMap == null) {
            routingContext.response().end("参数不得为空");
          }
          if(param!=null){
            if (multiMap != null) {
              Object value = multiMap.get(param.value());
              if (StringUtils.isEmpty(value) && param.required()) {
                  routingContext.response().end(param.value() + "不得为空");
                  return;
              } else {
                //参数类型处理
                paramTypeChange(value,cls,objList);
              }
            }
          }
          //处理requestBody
          if(requestBody!=null){
              RequestBody req=routingContext.body();
              JsonObject var=req.asJsonObject();
              if(var!=null && ! var.isEmpty()){
                  Map o=var.getMap();
                 Object data=JSONObject.parseObject(JSONObject.toJSONString(o),cls);
                  objList.add(data);
              }else {
                  objList.add(null);
              }
          }

  }

  private Param paramFieldHandler(Annotation[] annotations){
      for (int i = 0; i < annotations.length; i++) {
          Annotation annotation = annotations[i];
          if(annotation instanceof Param){
              Param param = (Param) annotation;
              return param;
          }
      }
      return null;
  }

  //参数类型改变
  private void paramTypeChange(Object obj,Class<?> cls,List<Object> objectList){
      System.out.println(cls.getName());
      if("java.lang.Integer".equals(cls.getName())){
          Integer value=ObjectTypeUtils.getInteger(String.valueOf(obj));
          objectList.add(value);
      }else {
          objectList.add(obj);
      }
  }

  private com.vert.annotations.RequestBody requestBodyHandler(Annotation[] annotations){
      for (int i = 0; i < annotations.length; i++) {
        Annotation annotation = annotations[i];
        if(annotation instanceof com.vert.annotations.RequestBody){
          com.vert.annotations.RequestBody requestBody = (com.vert.annotations.RequestBody) annotation;
          return requestBody;
        }
      }
      return null;
  }

}
